import express from 'express';
import { chromium, Page } from 'playwright';
import { z } from 'zod';
import path from 'node:path';

// 简易 MCP 风格：HTTP 端点充当工具，实际生产可接入 MCP SDK 的 transport
const app = express();
app.use(express.json({ limit: '10mb' }));

let page: Page | null = null;

async function ensurePage() {
  if (page) return page;
  const storagePath = path.resolve('state/xhs-storage.json');
  const browser = await chromium.launch({ headless: false });
  const context = await browser.newContext({ storageState: storagePath });
  page = await context.newPage();
  return page;
}

app.post('/open', async (req, res) => {
  try {
    const body = z.object({ url: z.string().url() }).parse(req.body);
    const p = await ensurePage();
    await p.goto(body.url, { waitUntil: 'networkidle' });
    res.json({ ok: true });
  } catch (e: any) {
    res.status(400).json({ ok: false, error: e?.message || String(e) });
  }
});

app.post('/click', async (req, res) => {
  try {
    const body = z.object({ selector: z.string() }).parse(req.body);
    const p = await ensurePage();
    await p.click(body.selector, { timeout: 30_000 });
    res.json({ ok: true });
  } catch (e: any) {
    res.status(400).json({ ok: false, error: e?.message || String(e) });
  }
});

app.post('/fill', async (req, res) => {
  try {
    const body = z.object({ selector: z.string(), value: z.string() }).parse(req.body);
    const p = await ensurePage();
    await p.fill(body.selector, body.value, { timeout: 30_000 });
    res.json({ ok: true });
  } catch (e: any) {
    res.status(400).json({ ok: false, error: e?.message || String(e) });
  }
});

app.post('/upload', async (req, res) => {
  try {
    const body = z.object({ selector: z.string(), files: z.array(z.string()).nonempty() }).parse(req.body);
    const p = await ensurePage();
    const input = await p.waitForSelector(body.selector, { timeout: 30_000 });
    await input.setInputFiles(body.files);
    res.json({ ok: true });
  } catch (e: any) {
    res.status(400).json({ ok: false, error: e?.message || String(e) });
  }
});

app.post('/wait', async (req, res) => {
  try {
    const body = z.object({ 
      selector: z.string(), 
      state: z.enum(['attached','visible','hidden','detached']).default('visible') 
    }).parse(req.body);
    const p = await ensurePage();
    await p.waitForSelector(body.selector, { state: body.state, timeout: 30_000 });
    res.json({ ok: true });
  } catch (e: any) {
    res.status(400).json({ ok: false, error: e?.message || String(e) });
  }
});

app.post('/screenshot', async (req, res) => {
  try {
    const p = await ensurePage();
    const screenshot = await p.screenshot({ type: 'png' });
    res.set('Content-Type', 'image/png');
    res.send(screenshot);
  } catch (e: any) {
    res.status(400).json({ ok: false, error: e?.message || String(e) });
  }
});

app.get('/health', (req, res) => {
  res.json({ ok: true, message: 'MCP-like Playwright server is running' });
});

const PORT = process.env.PORT || 3333;
app.listen(PORT, () => {
  console.log(`MCP-like server started on http://localhost:${PORT}`);
  console.log('Available endpoints:');
  console.log('  POST /open      - Navigate to URL');
  console.log('  POST /click     - Click element');
  console.log('  POST /fill      - Fill input field');
  console.log('  POST /upload    - Upload files');
  console.log('  POST /wait      - Wait for element');
  console.log('  POST /screenshot - Take screenshot');
  console.log('  GET  /health    - Health check');
});
